/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tds;

/**
 *
 * @author hoopaloopa
 */
public class SearchQuery {

	/**
	 * @return the since_id
	 */
	public String getSince_id() {
		return since_id;
	}

	/**
	 * @param since_id the since_id to set
	 */
	public void setSince_id(String since_id) {
		this.since_id = since_id;
		this.since_id_p = new Param ("since_id", since_id);
	}
	
	// Iterates through pages of the search
	public class Pages {
		protected int
				firstPage,
				lastPage,
				currentPage;
		
		public Pages(int numPages) {
			firstPage = 1;
			lastPage = numPages;
			currentPage = firstPage - 1;
		}
		
		public boolean hasNextPage() {
			return currentPage < lastPage;
		}
		
		public void nextPage() {
			++currentPage;
		}
		
		public void reset() {
			this.currentPage = this.firstPage - 1;
		}
		
		@Override
		public String toString() {
			return String.valueOf(currentPage);
		}
	}
	
	// Result type that Twitter will return
	public enum ResultType {
		mixed, recent, popular;
		
		@Override
		public String toString() {
			String string = "";
			switch (this) {
				case mixed: string = "mixed"; break;
				case recent: string = "recent"; break;
				case popular: string = "popular"; break;
			}
			return string;
		}
	}
	
	// Neatly formats the parameters as "name=value";
	public class Param {
		String name;
		String value;
		
		public Param(String name, String value) {
			this.name = name;
			this.value = value;
		}
		
		public String getName() {
			return name;
		}
		
		public String getValue() {
			return value;
		}
		
		@Override
		public String toString() {
			return name + "=" + value;
		}
	}
	
	// Constants
	final public int
			RESULTS_MAX = 1500,
			RPP_MAX = 100,
			NUM_PAGES = RESULTS_MAX / RPP_MAX;
	final public String BASE_SEARCH_URL = "http://search.twitter.com/search.json?";
	
	// Assumed values for now
	final protected String
			lang = "en",
			geocode = null,
			rpp = String.valueOf(RPP_MAX),
			until = null;
	final protected Pages pages = new Pages (NUM_PAGES);
	protected String
			query,
			since_id = null;
	protected ResultType resultType;
	
	// Parameters initialized based on String fields
	final private Param
			geocode_p = new Param("geocode", geocode),
			until_p = new Param("until", until),
			lang_p = new Param ("lang", lang),
			rpp_p = new Param("rpp", rpp),
			pages_p = new Param("page", pages.toString());
	protected Param
			since_id_p = new Param("since_id", getSince_id()),
			query_p,
			result_p;
	
	public SearchQuery(String q) {
		this(q, ResultType.mixed);
	}
	
	public SearchQuery(String q, ResultType type) {
		this.query = q;
		this.query_p = new Param("q", query);
		this.resultType = type;
		this.result_p = new Param("result_type", resultType.toString());
		
	}
	
	public boolean hasMorePages() {
		return this.pages.hasNextPage();
	}
	
	public void nextPage() {
		this.pages.nextPage();
		this.pages_p.value = String.valueOf(pages.currentPage);
	}
	
	public void refresh(SearchResult r) {
		this.pages.reset();
		this.setSince_id(r.getMaxIDStr());
	}
	
	@Override
	public String toString() {
		Param[] params = {since_id_p, until_p, lang_p, geocode_p, rpp_p, result_p, query_p, pages_p};
		String parameters = "";
		for (Param param : params) {
			
			if (param != null) {
				if (param.getName() != null && param.getValue() != null) {
					if (!parameters.isEmpty())
						parameters += "&";
					parameters += param;
				}
			}
		}
		
		return BASE_SEARCH_URL + parameters;
	}
}
